package com.didispace.web;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import com.didispace.service.ComputeClient;
import com.didispace.service.ComputeService;
import com.eshin.testcontext.ITestContext;
import com.eshin.testcontext.MyTestContextFactory;

@RestController
public class ConsumerController {

    @Autowired
    ComputeClient computeClient;
    @Autowired
    MyTestContextFactory factory;
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public Integer add() {
    	//相同的name只构造一次，第二次从缓存中取
    	ITestContext test = factory.getTestContextBean("helloeshin");
    	test.show();
    	ITestContext test1 = factory.getTestContextBean("helloeshin");
    	test1.show();
    	ITestContext test2 = factory.getTestContextBean("helloeshin111");
    	test2.show();
        return computeClient.add(10, 20);
    }
    private ConcurrentHashMap<DeferredResult<String>, Future<String>> futureCache = new ConcurrentHashMap<>();
    @Autowired
    private ComputeService computeService;
    @RequestMapping(value = "/addh", method = RequestMethod.GET)
    public String addHystrix() {
    	System.out.println(Thread.currentThread().getName());
        return computeService.addService();
    }
    
    private BlockingQueue<DeferredResultCache> queue1 = new ArrayBlockingQueue<DeferredResultCache>(10);;
    @RequestMapping(value = "/add1", method = RequestMethod.GET)
    @Async
    public DeferredResult<String> addHystrix1() throws Exception {
    	DeferredResultCache cache = new DeferredResultCache();
    	System.out.println("start===============================");
    	DeferredResult<String> result = new DeferredResult<>();
    	System.out.println(Thread.currentThread().getName());
    	Future<String> future = computeService.addService1();
    	cache.setFuture(future);
    	cache.setResult(result);
    	queue1.put(cache);
    	return result;
    }
    
  @PostConstruct
  public void rolling(){
  	Executors.newScheduledThreadPool(5).scheduleAtFixedRate(
				new Runnable(){
					@Override
				public void run() {
					System.out.println(Thread.currentThread().getName()+"start to bombing!");
					try {
						DeferredResultCache cache = queue1.take();
						cache.result.setResult("bombing!"+cache.getFuture().get());
						Thread.sleep(5000L);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println("bombed!!!!");
				}},
				6,
				2,
				TimeUnit.SECONDS);
  }
  
  
    class DeferredResultCache{
    	private Future<String>future;
    	private DeferredResult<String> result;
    	public Future<String> getFuture() {
			return future;
		}
		public void setFuture(Future<String> future) {
			this.future = future;
		}
		public DeferredResult<String> getResult() {
			return result;
		}
		public void setResult(DeferredResult<String> result) {
			this.result = result;
		}
		public DeferredResultCache() {
			// TODO Auto-generated constructor stub
		}
    }


}